#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QPushButton>
#include <cmath>
#include <QIcon>
#include <QList>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    qDebug() << "程序开始运行";
    version = " v1.0";
    setWindowTitle("芯片数量估算器" + version + " by liuv");
    //    setWindowIcon(QIcon(":/qt.webp"));

    computeBtn = ui->startBtn;
    // 将按钮的点击事件与槽函数连接起来
    connect(computeBtn, &QPushButton::clicked, this, &MainWindow::on_drawButton_clicked);

    chipHeightSpinBox = ui->chipHeightBox;
    chipWidthSpinBox = ui->chipWidthBox;
    hSpaceSpinBox = ui->hSpaceBox;
    vSpaceSpinBox = ui->vSpaceBox;
    waferDimComboBox = ui->comboBox;
    edgeSpaceSpinBox = ui->edgeSpaceBox;
    flatHeightSpinBox = ui->flatHeightBox;
    waferPriceBox = ui->waferPriceBox;
    yieldBox = ui->yieldBox;
    resultView = ui->lcdNumber;
    chipPriceView = ui->chipPriceLcd;
    drawWidget = ui->drawWidget;
    saveImageBtn = ui->saveImageBtn;

    waferDimComboBox->addItem("51", 51);
    waferDimComboBox->addItem("76", 76);
    waferDimComboBox->addItem("100", 100);
    waferDimComboBox->addItem("125", 125);
    waferDimComboBox->addItem("130", 130);
    waferDimComboBox->addItem("150", 150);
    waferDimComboBox->addItem("200", 200);
    waferDimComboBox->addItem("300", 300);
    waferDimComboBox->addItem("450", 450);

    yieldBox->setMaximum(100);
    waferPriceBox->setMaximum(9999999);


    resultView->setDigitCount(10);
    resultView->setSegmentStyle(QLCDNumber::Flat);
    chipPriceView->setDigitCount(10);
    chipPriceView->setSegmentStyle(QLCDNumber::Flat);

    chipHeightSpinBox->setValue(1);
    chipWidthSpinBox->setValue(1);
    hSpaceSpinBox->setValue(0.1);
    vSpaceSpinBox->setValue(0.1);
    waferDimComboBox->setCurrentIndex(2);
    edgeSpaceSpinBox->setValue(5);
    flatHeightSpinBox->setValue(10);
    yieldBox->setValue(100);
    waferPriceBox->setValue(100000);

    connect(saveImageBtn, &QPushButton::clicked, this, &MainWindow::on_saveImageBtn_clincked);
}

MainWindow::~MainWindow()
{
    qDebug() << "程序位于后台";
    delete ui;
}

void MainWindow::on_saveImageBtn_clincked(){
    qDebug() << "on_saveImageBtn_clincked";
    drawWidget->saveImage();
    //    drawWidget->saveImageToSvg();
}

void MainWindow::on_drawButton_clicked()
{
    chipWidth = chipWidthSpinBox->value();
    chipHeight = chipHeightSpinBox->value();
    hSpace = hSpaceSpinBox->value();
    vSpace = vSpaceSpinBox->value();
    waferDim = waferDimComboBox->currentData().toDouble();
    edgeSpace = edgeSpaceSpinBox->value();
    flatHeight = flatHeightSpinBox->value();
    waferPrice = waferPriceBox->value();
    yield = yieldBox->value();

    drawWidget->chipWidth = chipWidthSpinBox->value();
    drawWidget->chipHeight = chipHeightSpinBox->value();
    drawWidget->hSpace = hSpaceSpinBox->value();
    drawWidget->vSpace = vSpaceSpinBox->value();
    drawWidget->waferDim = waferDimComboBox->currentData().toDouble();
    drawWidget->edgeSpace = edgeSpaceSpinBox->value();
    drawWidget->flatHeight = flatHeightSpinBox->value();

    //    qDebug() << "输入内容为:\n";
    qDebug() << "chipWidth:" << chipWidth;
    qDebug() << "chipHeight:" << chipHeight;
    qDebug() << "hSpace:" << hSpace;
    qDebug() << "vSpace:" << vSpace;
    qDebug() << "waferDim:" << waferDim;
    qDebug() << "edgeSpace:" << edgeSpace;
    qDebug() << "flatHeight:" << flatHeight;
    qDebug() << "waferPrice:" << waferPrice;
    qDebug() << "yield:" << yield;

    compute();

}

void MainWindow::paintEvent(QPaintEvent *event)
{
    //    // 调用基类的绘图事件处理函数
    QMainWindow::paintEvent(event);
}

void MainWindow::compute(){
    bool canLoop;
    double baseX, baseY;
    double centerX, centerY;    //圆心位置
    double usableR;             //可用区域半径
    double r;
    double totalW, totalH;
    int count = 0;
    double chipCenterX, chipCenterY;
    double offsetX, offsetY;
    double res;
    double chipMaxLenght;

    drawWidget->pointList.clear();
    //    qDebug() << "计算前:" << count;
    baseX = 0;
    baseY = 0;
    centerX = waferDim / 2 + baseX;
    centerY = waferDim / 2 + baseY;
    usableR = waferDim / 2 - edgeSpace;
    r = waferDim / 2;

    offsetX = (vSpace / 2) + FMod(r, (chipWidth + vSpace));
    offsetY = (hSpace / 2) + FMod(r, (chipHeight + hSpace));
    totalW = offsetX;
    totalH = offsetY;
    canLoop = true;
    chipMaxLenght = twoPointDistance(0, 0, chipWidth, chipHeight);
    //    qDebug() << "offsetX:" << offsetX;
    while (canLoop) {
        chipCenterX = totalW + (chipWidth / 2);
        chipCenterY = totalH + (chipHeight / 2);
        res = chipNearestBorderPoint(centerX, centerY, chipCenterX, chipCenterY, chipWidth, chipHeight);

        if (res <= usableR && totalH + chipHeight <= waferDim - flatHeight) {
            count = count + 1;
            drawWidget->pointList.append(Point(totalW, totalH));
        }

        if (totalW > waferDim) {
            totalW = offsetX;
            if (totalH > waferDim) {
                canLoop = false;
            } else {
                totalH = totalH + chipHeight + hSpace;
            }
        } else {
            totalW = totalW + chipWidth + vSpace;
        }
    }
    qDebug() << "计算结果:" << count;


    drawWidget->startDraw(count);
    int yieldCount = count * yield / 100;
    resultView->display(yieldCount);
    int intValue = static_cast<int>(waferPrice / yieldCount * 100);
    chipPrice = static_cast<double>(intValue) / 100;

    qDebug() << "良品数量:" << yieldCount;
    qDebug() << "芯片单价:" << chipPrice;
    qDebug() << "intValue:" << intValue;
    qDebug() << "chipPrice:" << chipPrice;
    qDebug() << "waferDimSpinBox->currentData().toDouble():" << waferDimComboBox->currentData().toString();
    chipPriceView->display(chipPrice);
}

double MainWindow::twoPointDistance(double p1X, double p1Y, double p2X, double p2Y) {
    double dis, x, y;
    x = pow(p1X - p2X, 2);
    y = pow(p1Y - p2Y, 2);
    dis = sqrt(x + y);
    return dis;
}

double MainWindow::chipNearestBorderPoint(double centerX, double centerY, double chipCenterX, double chipCenterY, double cw, double ch) {
    double temp, result;
    temp = twoPointDistance(centerX, centerY, chipCenterX - cw / 2, chipCenterY - ch / 2);
    result = twoPointDistance(centerX, centerY, chipCenterX + cw / 2, chipCenterY - ch / 2);
    if (temp > result) {
        result = temp;
    }
    temp = twoPointDistance(centerX, centerY, chipCenterX - cw / 2, chipCenterY + ch / 2);
    if (temp > result) {
        result = temp;
    }
    temp = twoPointDistance(centerX, centerY, chipCenterX + cw / 2, chipCenterY + ch / 2);
    if (temp > result) {
        result = temp;
    }
    return result;
}

double MainWindow::FMod(double a, double b) {
    double result = a - (int)(a / b) * b;
    if (result >= -pow(2, -52) && result <= pow(2, -52)) {
        result = 0;
    }
    return result;
}
